#include "StdAfx.h"
#include ".\listener.h"
#include "CompletionPort.h"
#include "Connection.h"

namespace Lumin {
namespace Win32 {

CSocketListener::CSocketListener(int nPort):m_nListenPort(nPort),m_skListenner(INVALID_SOCKET),m_nData(0)
{

}

CSocketListener::~CSocketListener(void)
{

}

void CSocketListener::Shutdown()
{
	if(m_skListenner != INVALID_SOCKET){
		closesocket(m_skListenner);
		m_skListenner = INVALID_SOCKET;
		Wait();
	}
}

int CSocketListener::Run()
{
	m_skListenner = CSocket::listen(m_nListenPort);
	while (1) 
	{
		sockaddr_in addr;
		SOCKET skClient = CSocket::Accept(m_skListenner,addr);
		if(skClient != -1){
			CConnection* pConnection = new CConnection(::inet_ntoa(addr.sin_addr));
			if(pConnection != NULL)
			{
				pConnection->m_pISocketListener = this;
				CIOContext* pIOContext = new CIOContext();
				pIOContext->stream = CServer::Allocate();
				pIOContext->stream->AddRef();
				pIOContext->iop = WSA_IO_ACCEPT;
				pIOContext->conn = pConnection;
				pConnection->AttachSocket(skClient);
				CCompletionPort::GetInstance()->PostQueuedCompletionStatus((ULONG_PTR)pConnection,0,&pIOContext->overlapped);
			}else{
				closesocket(skClient);
			}
		}
		else if (WSAENOTSOCK == ::WSAGetLastError() ||
			WSAEINTR == ::WSAGetLastError() || 
			WSANOTINITIALISED == ::WSAGetLastError())
		{
			break;
		}
	}
	return 0;
}

}
}